/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package it.polimi.registration.business.security.boundary;

import it.polimi.registration.business.security.entity.Event;
import it.polimi.registration.business.security.entity.Location;
import it.polimi.registration.business.security.entity.Users;
import it.polimi.registration.business.security.entity.UsersEvent;
import it.polimi.registration.gui.security.ForecastBean;
import java.io.IOException;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.codehaus.jettison.json.JSONException;
import org.primefaces.model.ScheduleEvent;

/**
 *
 * @author Luca
 */
@Stateless
public class EventManager {

    @PersistenceContext
    EntityManager em;

    @Inject
    Principal principal;
    
    

    public void save(Event event) {

        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        Validator validator = factory.getValidator();
        Set<ConstraintViolation<Event>> constraintViolations = validator.validate(event);
        if (constraintViolations.size() > 0) {
            Iterator<ConstraintViolation<Event>> iterator = constraintViolations.iterator();
            while (iterator.hasNext()) {
                ConstraintViolation<Event> cv = iterator.next();
                System.err.println(cv.getRootBeanClass().getName() + "." + cv.getPropertyPath() + " " + cv.getMessage());

                //JsfUtil.addErrorMessage(cv.getRootBeanClass().getSimpleName() + "." + cv.getPropertyPath() + " " + cv.getMessage());
            }
        } else {
            em.persist(event);
        }
    }

    public void delete() {
        em.remove(getSelectedEvent());
    }

    private Object getSelectedEvent() {
        return em.find(Event.class, principal.getName());
    }

    public Event getEventByID(String id) {
        Long longID = Long.parseLong(id);
        Query query = em.createQuery("SELECT e from Event e Where e.id= :eventID").setParameter(("eventID"), longID);
        List<Event> eventLoaded = new ArrayList<>(query.getResultList());

        return eventLoaded.get(0);
    }

    public List<Event> loadCalendar(Users users) {
        Query query = em.createQuery("SELECT usev.event FROM UsersEvent usev WHERE (usev.users = :users AND (usev.accepted=true OR usev.creator=true))").setParameter(("users"), users);
        List<Event> eventLoaded = new ArrayList<>(query.getResultList());
      
        return (List) eventLoaded;
    }
    
    public List<Event> getAllEvent(){
        Query query = em.createNamedQuery("Select e from Event e");
        List<Event> eventLoaded = new ArrayList<>(query.getResultList());
        return (List) eventLoaded;
    }

    public List<Event> loadInvitations(Users users) {
        Query query = em.createQuery("SELECT usev.event FROM UsersEvent usev WHERE (usev.users = :users AND (usev.accepted=false AND usev.creator=false AND usev.seen=false))").setParameter(("users"), users);
        List<Event> eventLoaded = new ArrayList<>(query.getResultList());
        Query query2 = em.createQuery("SELECT usev.event.id FROM UsersEvent usev WHERE (usev.users = :users AND (usev.accepted=false AND usev.creator=false AND usev.seen=false))").setParameter(("users"), users);
        List<Long> lista = new ArrayList<>(query2.getResultList());

        for (int i = 0; i < eventLoaded.size(); i++) {
            eventLoaded.get(i).setId(lista.get(i));
        }

        return (List) eventLoaded;
    }

    public List<Long> loadAllEventById() {
        Query query = em.createQuery("SELECT e.id FROM Event e");
        List<Long> idLoaded = new ArrayList<>(query.getResultList());
        return (List) idLoaded;
    }

    public void updateEvent(Event event) {
        String tit = event.getTitle();
        Long ID = event.getId();
        Date sd = event.getStartDate();
        Date ed = event.getEndDate();
        Location loc = event.getLocation();
        String pref = event.getPreference();
        Query query1 = em.createQuery("UPDATE Event e SET e.title=:tit WHERE e.id=:ID");
        query1.setParameter("tit", tit);
        query1.setParameter("ID", ID);
        query1.executeUpdate();
        Query query2 = em.createQuery("UPDATE Event e SET e.startDate=:sd WHERE e.id=:ID");
        query2.setParameter("sd", sd);
        query2.setParameter("ID", ID);
        query2.executeUpdate();
        Query query3 = em.createQuery("UPDATE Event e SET e.endDate=:ed WHERE e.id=:ID");
        query3.setParameter("ed", ed);
        query3.setParameter("ID", ID);
        query3.executeUpdate();
        Query query4 = em.createQuery("UPDATE Event e SET e.location.city=:loc WHERE e.id=:ID");
        query4.setParameter("loc", loc.getCity());
        query4.setParameter("ID", ID);
        query4.executeUpdate();
        Query query5 = em.createQuery("UPDATE Event e SET e.preference=:pref WHERE e.id=:ID");
        query5.setParameter("pref", pref);
        query5.setParameter("ID", ID);
        query5.executeUpdate();

    }

    public void deleteEvent(Event event) {
        Query query = em.createQuery("DELETE FROM Event e WHERE e.id= :event").setParameter("event", event.getId());
        query.executeUpdate();
    }

    public List<Event> getEventWithPreference() {
        Query query = em.createQuery("Select e From Event e Where e.preference=true");
        List<Event> result = new ArrayList<>(query.getResultList());
        return result;
    }
    public boolean isCreator(Event event, Users users) {
        Query query = em.createQuery("SELECT ue FROM UsersEvent ue WHERE ue.event= :event and ue.users= :users").setParameter("event", event).setParameter("users", users);
        List<UsersEvent> result = new ArrayList<>(query.getResultList());
        return result.get(0).getCreator();
    }

}
